package com.hongxin.nw.netty.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hongxin.nw.netty.down.*;
import com.hongxin.nw.netty.model.Transfer;
import com.hongxin.nw.netty.mq_info.domain.AuthRequest;
import com.hongxin.nw.netty.server.AuthService;
import com.hongxin.nw.netty.utils.HttpClient4;
import com.hongxin.nw.netty.utils.JSONUtils;
import com.hongxin.nw.netty.utils.MyJson;
import com.hongxin.nw.netty.utils.pools.AsduStartPools;
import com.hongxin.nw.netty.utils.pools.ChannelPools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @remark
 * @author: GuoXiaolin
 * @date 2019/5/16 17:02
 * @Version 1.0
 * @Descibe  向设备发送指令的controller
 */
@Slf4j
@RestController
@RequestMapping("/cmd")
public class CMDController {

    //向设备发送U帧启动传输,,发送此指令,,设备才会主动发送信息到服务器(netty)
    @RequestMapping(value = "/start", method = RequestMethod.POST)
    public String startU(@RequestParam(value="code") String code) {

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new StartReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"发送U帧启动传输失败,设备离线", code).toJSONString();
        }
    }

    //向设备发送U帧停止传输
    @RequestMapping(value = "/stop", method = RequestMethod.POST)
    public String stopU(@RequestParam(value="code") String code) {

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new StopReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"发送U帧停止传输失败,设备离线", code).toJSONString();
        }
    }

    //确认心跳
    @RequestMapping(value = "/heartbeat", method = RequestMethod.POST)
    public String heartbeat(@RequestParam(value="code") String code) {

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new HeartBeatReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"确认心跳失败,设备离线", code).toJSONString();
        }
    }

    //TYPE = 103 , COT =6 ,时钟同步
    @RequestMapping(value = "/time_sync", method = RequestMethod.POST)
    public String time_sync(@RequestParam(value="code") String code){

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new TimeSyncReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"时间同步失败,设备离线", code).toJSONString();
        }
    }

    //远程启动充电(正常版本)
    @RequestMapping(value = "/start_charge", method = RequestMethod.POST)
    public String start_charge(@RequestParam(value="code") String code,
                               @RequestParam(value="bj") String bj,
                               @RequestParam(value="money") String money,
                               @RequestParam(value="uid") String uid,
                               @RequestParam(value="ctype") String cType,
                               @RequestParam(value="cparam") String cParam) {

        //ChannelPools.getCtx(code);
        Map<String,Object> data = new ConcurrentHashMap<>();
        data.put("code", code);
        data.put("bj", bj);
        data.put("money", money);
        data.put("uid", uid);
        data.put("cType", cType);
        data.put("cParam", cParam);
        Transfer transfer = new Transfer(code, data);
        ChannelRequest cr1 = new ChannelRequest(new StartChargeReq());

        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"远程启动充电(正常版本)失败,设备离线", code).toJSONString();
        }

    }


    //远程启动充电(临时计费策略版本)
    @RequestMapping(value = "/start_charge_b", method = RequestMethod.POST)
    public String start_charge_b(@RequestParam(value="code") String code,
                               @RequestParam(value="bj") String bj,
                               @RequestParam(value="money") String money,
                               @RequestParam(value="uid") String uid,
                               @RequestParam(value="ctype") String cType,
                               @RequestParam(value="cparam") String cParam,
                               @RequestParam(value="data") String data) {
        //ChannelPools.getCtx(code);
        Map<String,Object> map = new ConcurrentHashMap<>();
        map.put("code", code);
        map.put("cType", cType);
        map.put("cParam", cParam);
        map.put("bj", bj);
        map.put("money", money);
        map.put("uid", uid);
        map.put("data", data);
        Transfer transfer = new Transfer(code, map);
        ChannelRequest cr1 = new ChannelRequest(new TempStartChargeReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"远程启动充电(临时计费策略版本)失败,设备离线", code).toJSONString();
        }
    }

    //远程终止充电
    @RequestMapping(value = "/end_charge", method = RequestMethod.POST)
    public String end_charge(@RequestParam(value="code") String code,
                             @RequestParam(value="bj") String bj,
                             @RequestParam(value="uid") String uid) {

        //ChannelPools.getCtx(code);
        Map<String,Object> map = new ConcurrentHashMap<>();
        map.put("code", code);
        map.put("bj", bj);
        map.put("uid", uid);
        Transfer transfer = new Transfer(code, map);
        ChannelRequest cr1 = new ChannelRequest(new EndChargeReq());

        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"远程终止充电失败,设备离线", code).toJSONString();
        }
    }


    //下发计费模型下行数据
    @RequestMapping(value = "/send_billing", method = RequestMethod.POST)
    public String send_billing(@RequestParam(value="data") String data) {
        JSONObject json = JSONObject.parseObject(data);
        String code = json.getString("code");
        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code, json);
        ChannelRequest cr1 = new ChannelRequest(new BillingReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"下发计费失败,设备离线", code).toJSONString();
        }
    }

    //批量下发计费模型下行数据
    @RequestMapping(value = "/batch_billing", method = RequestMethod.POST)
    public String batch_billing(@RequestParam(value="data") String data) {
        JSONArray arr = JSONObject.parseArray(data);
        JSONObject resJson = new JSONObject();
        for (int i=0;i<arr.size();i++){
            JSONObject json = arr.getJSONObject(i);
            String code = json.getString("code");//设备编码
            //ChannelPools.getCtx(code);
            Transfer transfer = new Transfer(code, json);
            ChannelRequest cr1 = new ChannelRequest(new BillingReq());
            try {
                cr1.execute(transfer).toJSONString();
                log.info("下发设备{}计费:{}", code, json.toJSONString());
            } catch (Exception e) {
                log.info("{}", e.getMessage());
                resJson.put(code, e.getMessage());
            }
        }
        return JSONUtils.getRoot(0,"批量下发成功", resJson.toJSONString()).toJSONString();
    }

    //充电设备上报参数设置
    @RequestMapping(value = "/paramSetUp", method = RequestMethod.POST)
    public String paramSetUp(@RequestParam(value="data") String data) {
        JSONObject jsonObject = JSONObject.parseObject(data);
        String code = jsonObject.getString("code");
        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code, jsonObject);
        ChannelRequest cr1 = new ChannelRequest(new ParamSetUpReq());

        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"充电设备上报参数设置失败,设备离线", code).toJSONString();
        }
    }

    //计数量总召
    @RequestMapping(value = "/c_summon", method = RequestMethod.POST)
    public String c_summon(@RequestParam(value="code") String code) {

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new CSummonReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"计数量总召失败,设备离线", code).toJSONString();
        }
    }

    //总召
    @RequestMapping(value = "/summon", method = RequestMethod.POST)
    public String summon(@RequestParam(value="code") String code) {

        //ChannelPools.getCtx(code);
        Transfer transfer = new Transfer(code);
        ChannelRequest cr1 = new ChannelRequest(new SummonReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"总召失败,设备离线", code).toJSONString();
        }
    }

    //远程升级
    @RequestMapping(value = "/upgrade", method = RequestMethod.POST)
    public String Upgrade(@RequestParam(value="code") String code,
                          @RequestParam(value="order") String order,
                          @RequestParam(value="fip") String fip,
                          @RequestParam(value="fport") String fport,
                          @RequestParam(value="fuser") String fuser,
                          @RequestParam(value="fpass") String fpass,
                          @RequestParam(value="fpath") String fpath,
                          @RequestParam(value="ffile") String ffile,
                          @RequestParam(value="fcode") String fcode,
                          @RequestParam(value="hv") String hv,
                          @RequestParam(value="sv") String sv) {


        //ChannelPools.getCtx(code);
        Map<String, String> map = new ConcurrentHashMap<>();
        map.put("order", order);
        map.put("fip", fip);
        map.put("fport", fport);
        map.put("fuser", fuser);
        map.put("fpass", fpass);
        map.put("fpath", fpath);
        map.put("ffile", ffile);
        map.put("fcode", fcode);
        map.put("hv", hv);
        map.put("sv", sv);
        Transfer transfer = new Transfer(code, map);
        ChannelRequest cr1 = new ChannelRequest(new UpgradeReq());
        try {
            return cr1.execute(transfer).toJSONString();
        } catch (Exception e) {
            log.info("{}", e.getMessage());
            return JSONUtils.getRoot(-1,"远程升级失败,设备离线", code).toJSONString();
        }
    }

    //测试 鉴权
    @RequestMapping(value = "/verify", method = RequestMethod.GET)
    public String verify(){

        AuthRequest authRequest = new AuthRequest();
        authRequest.setUserId("25263355792");//1542065942
        authRequest.setAuthenticationMode("0");
        authRequest.setBalance("10000.0");
        authRequest.setInterfaceNumber("1");
        authRequest.setMachineId("12345678");
        authRequest.setNumberPlate("0");
        authRequest.setUpdateBalance("false");

        AuthService authService = new AuthService();
        MyJson httpRes;
        try {
            httpRes = authService.auth(authRequest);
        } catch (Exception e) {
            return JSONUtils.getRoot(-1,e.getMessage(),"--").toJSONString();
        }

        return httpRes.getStringdata();
    }

    //测试 计费下发
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public String test(){

        JSONObject jsonObject1 = new JSONObject();
        jsonObject1.put("startTime","00:00"); //    第N个时段起始时间点	BIN码	2Byte	高字节：小时（0-24）  低字节：分钟（0-60）
        jsonObject1.put("identify","1"); //    第N个时段标志	BIN码	1Byte	1：尖时段；2：峰时段 3：平时段，4：谷时段
        jsonObject1.put("electricFee","500001"); //9N+2	第N个时段尖电价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("fEPrice","500001"); //9N+3	第N个时段峰电价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("pEPrice","500001"); //9N+4	第N个时段平电价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("gEPrice","500001"); //9N+5	第N个时段谷电价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("serverPrice","500001"); //9N+6	第N个服务费单价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("occupancyPrice","500001"); //9N+7	第N个占位费单价	BIN码	4Byte	精确到小数点后五位
        jsonObject1.put("subscriptionPrice","500001"); //9N+8	第N个预约费单价	BIN码	4Byte	精确到小数点后五位

        JSONArray jsonArray = new JSONArray();
        jsonArray.add(jsonObject1);

        JSONObject json = new JSONObject();
        json.put("code","12345678");//设备编号
        json.put("bj","0");//枪口号
        json.put("bid","12345678");//计费id
        json.put("aotTime","1560734273000");//生效时间
        json.put("sotTime","1592356673000");//失效时间
        json.put("excStatus","0001");//执行状态
        json.put("MeterType","0001");//计费类型
        json.put("timeNumb","2");//时段数
        json.put("timeInfos",jsonArray.toString());

        Map<String, Object> data = new HashMap<>();
        data.put("data", json.toString());

        try {
            HttpClient4.doPost("http://192.168.1.126:8081/cmd/send_billing", data);
        } catch (Exception e) {
            return JSONUtils.getRoot(-1, e.getMessage(), "--").toJSONString();
        }
        return "s";
    }

    //测试 设备移除
    @RequestMapping(value = "/removeCode", method = RequestMethod.GET)
    public String removeCode(){
        ChannelPools.removeCtx("302000000000254");
        return JSONUtils.getRoot(0,"设备已移除","--").toJSONString();
    }
    //测试 a s d u 移除
    @RequestMapping(value = "/removeA", method = RequestMethod.GET)
    public String removeA(){
        AsduStartPools.removeAsduStart("302000000000254");
        return JSONUtils.getRoot(0,"设备启动数据已移除","--").toJSONString();
    }
}
